package com.cndw.kungfu.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.cndw.kungfu.comm.AccessFlag;
import com.cndw.kungfu.config.ArtifactConfig;
import com.cndw.kungfu.config.ConstantsCost;
import com.cndw.kungfu.config.ConstantsDayIntKey;
import com.cndw.kungfu.config.ConstantsFlag;
import com.cndw.kungfu.config.ConstantsIntKey;
import com.cndw.kungfu.config.ConstantsLevel;
import com.cndw.kungfu.config.ConstantsLog;
import com.cndw.kungfu.config.GoodsEffectConfig;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.ext.LanguageLib;
import com.cndw.kungfu.ext.NumberProcesser;
import com.cndw.kungfu.ext.StringProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.player.domain.Artifact;
import com.cndw.kungfu.model.player.domain.ArtifactSub;
import com.cndw.kungfu.model.sys.LogServer;
import com.cndw.kungfu.vo.goodsvo.GoodsVO;
import com.cndw.rpg.annotation.Controller;
import com.cndw.rpg.framework.ResponseMessage;
import com.cndw.rpg.framework.Session;

/**
 * 上古神器的界面
 * 
 * @author fantadust [9677889@qq.com]
 * @date 2012-8-27 下午3:34:31
 */
@Controller
public class ArtifactController {

	/**
	 * 神器显示界面
	 * 
	 * @param session
	 * @return
	 */
	public ResponseMessage actShow(Session session, int actId) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		if (player.getLevel() < ConstantsLevel.lv60act) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.level", ConstantsLevel.lv60act));
		}
		if (actId > 2 || actId <=0) {
			return null;
		}
		if (actId == 2 && player.getDataInfo().intDataGet(ConstantsIntKey.anePass) < 503) {
			return null;
		}
		Artifact artifact = player.getDataInfo().getArtifactByInit(true);
		
		ArtifactSub aSub = artifact.getSubByInit(actId, true);
		List<GoodsVO> baoFuVOs = new ArrayList<GoodsVO>();
		int stackNum = 0;
		for (int i = 0; i < GoodsEffectConfig.artBaoFuIds.length; i++) {
			GoodsVO baoFuVO = Context.getGoodsServer().getModeById(GoodsEffectConfig.artBaoFuIds[i]).toGoodsVO();
			stackNum = player.getPlayerBoxs().getStackNum(GoodsEffectConfig.artBaoFuIds[i]);
			baoFuVO.setStackNum(stackNum);
			baoFuVOs.add(baoFuVO);
		}

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("aScore", aSub.getScore());
		map.put("aNodes", aSub.getNodes());
		map.put("aLevel", aSub.getLevel());
		map.put("attris", aSub.getAttris());
		map.put("aFourbuff", aSub.getFourBuff());
		map.put("baoFuVOs", baoFuVOs);
		map.put("anePass", player.getDataInfo().intDataGet(ConstantsIntKey.anePass));
		map.put("at", player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.aat));

		return ResponseMessage.getSuccMessage(map);
	}

	public ResponseMessage actBag(Session session) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		if (player.getLevel() < ConstantsLevel.lv60act) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.level", ConstantsLevel.lv60act));
		}
		Artifact artifact = player.getDataInfo().getArtifactByInit(true);
		if (artifact == null) {
			return null;
		}
		int ane = player.getDataInfo().intDataGet(ConstantsIntKey.ane);
		int anf = player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.anf);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("bags", artifact.getBags());
		map.put("ane", ane);
		map.put("anf", 2 - anf);
		map.put("actUpRate", ArtifactConfig.actUpRate);
		map.put("actUpGoldBase", ArtifactConfig.actUpGoldBase);

		return ResponseMessage.getSuccMessage(map);
	}

	/**
	 * 提升境界
	 * 
	 * @param session
	 * @param actId
	 * @param baoFuNum
	 * @param autoStore
	 * @return
	 */
	@AccessFlag(ConstantsFlag.fucNewChk)
	public ResponseMessage actUpgrade(Session session, int actId, int baoFuNum, int autoStore) {
		if (baoFuNum < 0 || autoStore < 0) {
			return null;
		}
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Artifact artifact = player.getDataInfo().getArtifact();
		if (artifact == null) {
			return null;
		}
		ArtifactSub aSub = artifact.getSub(actId);
		if (aSub == null) {
			return null;
		}
		if (aSub.getLevel() >= ArtifactConfig.actUpMax) {
			return null;
		}
		int oldLevel = aSub.getLevel();
		int realmType = NumberProcesser.ceil(oldLevel + 1, 10);
		int step = oldLevel % 10;
		int costGold = ArtifactConfig.actUpGoldBase + (realmType - 1);

		if (player.getGoldAll() < costGold) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.gold"));
		}

		int goodsType = step >= 7 ? 2 : step <= 3 ? 0 : 1;//3级以下初级，4-6级中级，7级以上高级
		if (baoFuNum > 0) {
			
			if (player.getPlayerBoxs().getStackNum(GoodsEffectConfig.artBaoFuIds[goodsType]) < baoFuNum) {
				if (autoStore == 1) {
					if (!Context.getGoodsServer().buyStore(player, GoodsEffectConfig.artBaoFuIds[goodsType], baoFuNum,costGold)) {
						return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.gold"));
					}
				} else {
					return ResponseMessage.ticpErrMsg(LanguageLib.get("artifac.upgrade.num", baoFuNum));
				}
			} else {
				player.getPlayerBoxs().costGoods(GoodsEffectConfig.artBaoFuIds[goodsType], baoFuNum);
			}
		}
		int rate = ArtifactConfig.actUpRate[step] + baoFuNum * 5;
		rate = rate > 100 ? 100 : rate;
		boolean suc = NumberProcesser.isWinning(rate, 100);

		player.alterGoldAll(-costGold);
		LogServer.costEventLog(session.getUid(), costGold, ConstantsCost.actUp);
		boolean fall = false;
		if (suc) {
			aSub.setLevel(oldLevel + 1);
		} else {
			if (step > 1) {
				aSub.setLevel(oldLevel - 1);
				fall = true;
			}
		}

		player.commitSync();
		player.getDataInfo().commitSync();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("aLevel", aSub.getLevel());
		map.put("suc", suc);
		map.put("fall", fall);
		map.put("gold", player.getGold());
		map.put("goldBing", player.getGoldBing());
		
		if (suc || fall) {
			Context.getPlayerServer().clacProperties(player);
			map.put("player", player.toPlayerVO());
		}
		map.put("attris", aSub.getAttris());
		LogServer.recordLog(player, ConstantsLog.forge, 10201, actId, costGold, baoFuNum, suc, fall, aSub.getLevel());

		return ResponseMessage.getSuccMessage(map);
	}

	public ResponseMessage actInstall(Session session, int actId, int bagId, int nId) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Artifact artifact = player.getDataInfo().getArtifact();
		if (artifact == null) {
			return null;
		}
		ArtifactSub aSub = artifact.getSub(actId);
		if (aSub == null || !aSub.isIdle(nId)) {
			return null;
		}
		int[] bagNode = artifact.removeNode(bagId);
		if (bagNode == null) {
			return null;
		}
		aSub.nodeInstall(nId, bagNode);

		player.clacProperties();

		player.getDataInfo().commitSync();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("bagId", bagId);
		map.put("actId", actId);
		map.put("nId", nId);
		map.put("player", player.toPlayerVO());
		map.put("attris", aSub.getAttris());
		map.put("aFourbuff", aSub.getFourBuff());
		return ResponseMessage.getSuccMessage(map);
	}

	public ResponseMessage actUninstall(Session session, int actId, int nId, int bagId) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Artifact artifact = player.getDataInfo().getArtifact();
		if (artifact == null) {
			return null;
		}
		if (!artifact.isBlank(bagId)) {
			return null;
		}
		ArtifactSub aSub = artifact.getSub(actId);
		aSub.setId(actId);
		if (aSub == null || aSub.isIdle(nId)) {
			return null;
		}
		int[] node = aSub.removeNode(nId);
		if (node != null) {
			artifact.bagPut(bagId, node);
		}

		player.clacProperties();
		player.getDataInfo().commitSync();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("bagId", bagId);
		map.put("actId", actId);
		map.put("nId", nId);
		map.put("player", player.toPlayerVO());
		map.put("attris", aSub.getAttris());
		map.put("aFourbuff", aSub.getFourBuff());
		return ResponseMessage.getSuccMessage(map);
	}

	public ResponseMessage nodeUpgrade(Session session, int actId, int nId, boolean useGoods) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Artifact artifact = player.getDataInfo().getArtifact();
		if (artifact == null) {
			return null;
		}
		ArtifactSub aSub = artifact.getSub(actId);
		if (aSub == null || aSub.isIdle(nId)) {
			return null;
		}
		int[] node = aSub.getNode(nId);
		if (node[0] >= 4) {
			return null;
		}
		int costGold = ArtifactConfig.nodeUpGold[node[0]];
		int costNum = costGold / 10;
		int haveNum = player.getPlayerBoxs().getStackNum(GoodsEffectConfig.actNodeUpGoodsId);
		if (useGoods && haveNum < costNum) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.goods"));
		}else if (!useGoods && player.getGoldAll() < costGold) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.gold"));
		}
		if (useGoods) {
			player.getPlayerBoxs().costGoods(GoodsEffectConfig.actNodeUpGoodsId, costNum);
			haveNum -= costNum;
		} else {
			costNum = 0;//不消耗符
			player.alterGoldAll(-costGold);
			LogServer.costEventLog(session.getUid(), costGold, ConstantsCost.actNodeUp);
		}
		node[0] = node[0] + 1;
		node[2] = NumberProcesser.percentClac(node[2], 20);
		node[4] = NumberProcesser.percentClac(node[4], 20);
		node[6] = NumberProcesser.percentClac(node[6], 20);

		player.clacProperties();

		player.commitSync();
		player.getDataInfo().commitSync();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("gold", player.getGold());
		map.put("goldBing", player.getGoldBing());
		map.put("player", player.toPlayerVO());
		map.put("node", node);
		map.put("attris", aSub.getAttris());
		map.put("aFourbuff", aSub.getFourBuff());
		LogServer.recordLog(player, ConstantsLog.forge, 10202, actId, nId, useGoods ? 0 : costGold, node[0], StringProcesser.toString(node), useGoods, costNum, haveNum);

		return ResponseMessage.getSuccMessage(map);
	}

	public ResponseMessage nodeGrid(Session session, int actId, int nId) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Artifact artifact = player.getDataInfo().getArtifact();
		if (artifact == null) {
			return null;
		}
		ArtifactSub aSub = artifact.getSub(actId);
		if (aSub == null || aSub.isIdle(nId)) {
			return null;
		}
		int[] node = aSub.getNode(nId);
		if (node[7] >= 3) {
			return null;
		}
		int costGold = ArtifactConfig.nodeGirdGold[node[7]];
		if (player.getGoldAll() < costGold) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.gold"));
		}
		int girdNew = node[7] + 1;
		player.alterGoldAll(-costGold);
		node[7] = girdNew;

		Set<Integer> types = new HashSet<Integer>();
		types.add(node[1]);
		types.add(node[3]);
		int aType = 0, aLevel = 0;
		do {
			int[] rates = ArtifactConfig.getRate(node[0]);
			int indexId = NumberProcesser.rateIndex(rates, 10000);
			int[] typeArr = ArtifactConfig.getId(indexId);
			aType = typeArr[0];
			aLevel = typeArr[1];
		} while (types.contains(aType));

		int[] atts = ArtifactConfig.getAttri(aType);

		node[girdNew * 2 + 1 - 2] = aType;
		node[girdNew * 2 + 2 - 2] = NumberProcesser.mtRand(atts[aLevel], atts[aLevel + 1]);

		player.commitSync();
		player.getDataInfo().commitSync();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("gold", player.getGold());
		map.put("goldBing", player.getGoldBing());
		map.put("node", node);
		map.put("attris", aSub.getAttris());
		map.put("aFourbuff", aSub.getFourBuff());
		LogServer.costEventLog(session.getUid(), costGold, ConstantsCost.actNodeGrid);
		LogServer.recordLog(player, ConstantsLog.forge, 10203, actId, nId, costGold, node[7], StringProcesser.toString(node));

		return ResponseMessage.getSuccMessage(map);

	}

	public ResponseMessage nodeForge(Session session, int actId, int nId, int useType, int lockType) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Artifact artifact = player.getDataInfo().getArtifact();
		if (artifact == null) {
			return null;
		}
		ArtifactSub aSub = artifact.getSub(actId);
		if (aSub == null || aSub.isIdle(nId)) {
			return null;
		}
		if (useType < 0 || useType > 3) {
			return null;
		}
		int anf = player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.anf);
		if (useType == 0 && anf >= 2) {
			return null;
		}

		int coef = 1;
		int[] node = aSub.getNode(nId);
		Set<Integer> types = new HashSet<Integer>();
		for (int i = 0; i < node[7]; i++) {
			int aType = node[i * 2 + 1];
			if ((lockType & (1 << i)) > 0) {
				types.add(aType);
				coef++;
			}
		}
		int costExt = useType == 1 ? 1 * coef : 0;//调整碎魄洗炼由原来的3碎魄洗炼一次改为1碎魄洗炼一次
		int costGold = useType == 2 ? 10 * coef : 0;
		
		int costAsset = 0;
		if (useType == 3) {
			int assetTimes = player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.aat) + 1;
			int base = assetTimes <= 5 ? ArtifactConfig.forgeAssetBase : (100 + (20 * (assetTimes - 5))) * (ArtifactConfig.forgeAssetBase / 100);
			costAsset = player.getLevel() * base * coef;
		}
		if (costAsset > 0 && player.getAsset() < costAsset) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.asset"));
		}
		
		if (costGold > 0 && player.getGoldAll() < costGold) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.gold"));

		}
		int nodeExt = player.getDataInfo().intDataGet(ConstantsIntKey.ane);
		if (costExt > 0 && nodeExt < costExt) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("artifac.ane.err", costExt));
		}
		if (useType == 0) {
			anf++;
			player.getDataInfo().getEveryDay().intDataSet(ConstantsDayIntKey.anf, anf);
		}
		if (costAsset > 0) {
			player.alterAsset(-costAsset);
			player.getDataInfo().getEveryDay().intDataAlter(ConstantsDayIntKey.aat, 1);
		}
		if (costGold > 0) {
			player.alterGoldAll(-costGold);
		}
		if (costExt > 0) {
			nodeExt = nodeExt - costExt;
			player.getDataInfo().intDataSet(ConstantsIntKey.ane, nodeExt);
		}

		for (int i = 0; i < node[7]; i++) {
			int aType = node[i * 2 + 1];
			if ((lockType & (1 << i)) <= 0) {
				int aLevel = 0;
				do {
					int[] rates = ArtifactConfig.getRate(node[0]);
					int indexId = NumberProcesser.rateIndex(rates, 10000);
					int[] typeArr = ArtifactConfig.getId(indexId);
					aType = typeArr[0];
					aLevel = typeArr[1];
				} while (types.contains(aType));

				int[] atts = ArtifactConfig.getAttri(aType);

				node[i * 2 + 1] = aType;
				node[i * 2 + 2] = NumberProcesser.mtRand(atts[aLevel], atts[aLevel + 1]);
			}
			types.add(aType);
		}
		// 光棍节活动：记录总共洗练次数 结束时间：11月12日23:59:59 
//		player.getDataInfo().getEveryDay().intDataAlter(ConstantsDayIntKey.twa, 1);
		
		player.fullBloodMagic();
		player.clacProperties();
		player.commitSync();
		player.getDataInfo().commitSync();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("at", player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.aat));
		map.put("gold", player.getGold());
		map.put("goldBing", player.getGoldBing());
		map.put("asset", player.getAsset());
		map.put("player", player.toPlayerVO());
		map.put("node", node);
		map.put("ane", nodeExt);
		map.put("anf", 2 - anf);
		map.put("attris", aSub.getAttris());
		map.put("aFourbuff", aSub.getFourBuff());
		if (costGold > 0) {
			LogServer.costEventLog(session.getUid(), costGold, ConstantsCost.actNodeForge);
		}
		
		LogServer.recordLog(player, ConstantsLog.forge, 10204, actId, nId, useType, lockType, costGold, costExt, nodeExt, StringProcesser.toString(node), costAsset);

		return ResponseMessage.getSuccMessage(map);
	}

	public ResponseMessage nodeForgeSingle(Session session, int actId, int nId, int indexId) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Artifact artifact = player.getDataInfo().getArtifact();
		if (artifact == null) {
			return null;
		}
		ArtifactSub aSub = artifact.getSub(actId);
		if (aSub == null || aSub.isIdle(nId)) {
			return null;
		}
		int costGold = ArtifactConfig.nodeForgeSingleGold;
		if (player.getGoldAll() < costGold) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.gold"));
		}
		int[] node = aSub.getNode(nId);
		int aType = node[indexId * 2 - 1];
		int aValue = node[indexId * 2];
		int[] atts = ArtifactConfig.getAttri(aType);
		int xxx = NumberProcesser.nearMaxIndex(atts, aValue);
		if (xxx!= 4) {
			return null;
		}
		//光棍节活动：记录总共洗练次数 结束时间：11月12日23:59:59 
//		player.getDataInfo().getEveryDay().intDataAlter(ConstantsDayIntKey.twa, 1);
				
		node[indexId * 2] = NumberProcesser.mtRand(atts[xxx], atts[xxx+1]);
		player.alterGoldAll(-costGold);
		player.clacProperties();
		player.commitSync();
		player.getDataInfo().commitSync();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("gold", player.getGold());
		map.put("goldBing", player.getGoldBing());
		map.put("player", player.toPlayerVO());
		map.put("node", node);
		map.put("attris", aSub.getAttris());
		map.put("aFourbuff", aSub.getFourBuff());
		LogServer.costEventLog(session.getUid(), costGold, ConstantsCost.actNodeForgeSingle);
		return ResponseMessage.getSuccMessage(map);

	}
	
	public ResponseMessage nodeFeed(Session session,int actId, int nId){
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Artifact artifact = player.getDataInfo().getArtifact();
		if (artifact == null) {
			return null;
		}
		ArtifactSub aSub = artifact.getSub(actId);
		if (aSub == null || aSub.isIdle(nId)) {
			return null;
		}
		if (!player.getPlayerBoxs().isHaveGoods(ArtifactConfig.nodeForgeGoodsId)) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.goods"));
		}
		player.getPlayerBoxs().costGoods(ArtifactConfig.nodeForgeGoodsId, 1);
		int[] node = aSub.getNode(nId);
		for (int i = 0; i < 3; i++) {
			int aType = node[i * 2 + 1];
			int aVale = node[i * 2 + 2];
			if (aType <= 0 ) {
				continue;
			}
			aVale = aVale + ArtifactConfig.nodeForgeGoodsAdd[aType];
			aVale = aVale >= ArtifactConfig.getAttri(aType)[5] ? ArtifactConfig.getAttri(aType)[5] :aVale;
			node[i * 2 + 2] = aVale;
		}
		
		
		player.clacProperties();
		player.commitSync();
		player.getDataInfo().commitSync();
		

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("gold", player.getGold());
		map.put("goldBing", player.getGoldBing());
		map.put("player", player.toPlayerVO());
		map.put("node", node);
		map.put("attris", aSub.getAttris());
		map.put("aFourbuff", aSub.getFourBuff());
		return ResponseMessage.getSuccMessage(map);
	}

	public ResponseMessage nodeMelt(Session session, int bagId) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Artifact artifact = player.getDataInfo().getArtifact();
		if (artifact == null) {
			return null;
		}
		int[] nodes = artifact.removeNode(bagId);
		if (nodes == null) {
			return null;
		}
		int gotExt = ArtifactConfig.meltNum[nodes[0]];

		int ane = player.getDataInfo().intDataGet(ConstantsIntKey.ane);
		ane += gotExt;
		player.getDataInfo().intDataSet(ConstantsIntKey.ane, ane);
		player.getDataInfo().commitSync();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("ane", ane);
		map.put("bagId", bagId);
		LogServer.recordLog(player, ConstantsLog.forge, 10205, bagId, gotExt, StringProcesser.toString(nodes));

		return ResponseMessage.getSuccMessage(map);
	}

	public ResponseMessage nodeExchange(Session session, int type) {
		if (type <= 0 || type > 4) {
			return null;
		}
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Artifact artifact = player.getDataInfo().getArtifact();
		if (artifact == null || !artifact.isIdle()) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("goods.use.actfull"));
		}
		int ane = player.getDataInfo().intDataGet(ConstantsIntKey.ane);
		int costAne = ArtifactConfig.nodeExchange[type];
		if (ane < costAne) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("artifac.ane.err", costAne));
		}
		ane -= costAne;
		player.getDataInfo().intDataSet(ConstantsIntKey.ane, ane);

		int bagId = artifact.bagAdd(type);
		int[] node = artifact.getNodeByBag(bagId);

		player.getDataInfo().commitSync();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("ane", ane);
		map.put("bagId", bagId);
		map.put("node", node);

		LogServer.recordLog(player, ConstantsLog.forge, 10206, type, costAne, ane, StringProcesser.toString(node));

		return ResponseMessage.getSuccMessage(map);
	}

}
